package com.andengine.editor.textureregioneditor;

import com.andengine.editor.Utils;
import com.swingson.exceptions.ErrorMessageException;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.TexturePaint;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;
import javax.imageio.ImageIO;
import javax.swing.JPanel;

/**
 * @author sad
 */
public class PreviewPanel extends JPanel {

    private BufferedImage image;
    private int xOffset;
    private int yOffset;
    private BufferedImage transparentImageStub;
    private int columnCount = 1;
    private int rowCount = 1;

    public int getColumnCount() {
        return columnCount;
    }

    public void setColumnCount(int columnCount) {
        this.columnCount = columnCount;
    }

    public int getRowCount() {
        return rowCount;
    }

    public void setRowCount(int rowCount) {
        this.rowCount = rowCount;
    }

    public PreviewPanel() {
        try {
            try (InputStream stream = TextureFileWithThumbnail.class.getResourceAsStream("/com/andengine/editor/image/transparentImageStub.png")) {
                if (stream == null) {
                    throw new ErrorMessageException("File transparentImageStub.png is not found in spriteeditor package");
                }

                transparentImageStub = ImageIO.read(stream);
            }
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    public void setImage(BufferedImage image) {
        this.image = image;
        setPreferredSize(new Dimension(image.getWidth() + 20, image.getHeight() + 20));
        recalculateOffsets();
    }

    public void recalculateOffsets() {
        if (image != null) {
            xOffset = getWidth() / 2 - image.getWidth() / 2;
            yOffset = getHeight() / 2 - image.getHeight() / 2;
        }
    }

    @Override
    public void paint(Graphics g) {
        super.paint(g);
        if (image == null) {
            Utils.drawStringInCenterOfRect("No image", 0, 0, getWidth(), getHeight(), g, this);
        } else {
            //draw transparent background
            Graphics2D g2d = (Graphics2D) g;
            g2d.setPaint(new TexturePaint(transparentImageStub, new Rectangle(transparentImageStub.getWidth(), transparentImageStub.getHeight())));
            g2d.fill(new Rectangle(xOffset, yOffset, image.getWidth(), image.getHeight()));
            //draw actual image
            g.drawImage(image, xOffset, yOffset, this);
            g.setColor(Color.LIGHT_GRAY);
            g.drawRect(xOffset - 1, yOffset - 1, image.getWidth() + 1, image.getHeight() + 1);
            if (columnCount > 1 || rowCount > 1) {
                drawGrid(g2d);
            }
        }
    }

    private void drawGrid(Graphics2D g) {
        g.setXORMode(Color.BLACK);
        float tileWidth = (float) image.getWidth() / (float) columnCount;
        float tileHeight = (float) image.getHeight() / (float) rowCount;
        float x = tileWidth + xOffset;
        for (int i = 0; i < columnCount - 1; i++) {
            g.drawLine((int) x, yOffset, (int) x, yOffset + image.getHeight() - 1);
            x += tileWidth;
        }
        float y = tileHeight + yOffset;
        for (int j = 0; j < rowCount - 1; j++) {
            g.drawLine(xOffset, (int) y, xOffset + image.getWidth() - 1, (int) y);
            y += tileHeight;
        }
    }

    public int getFrameCount() {
        return columnCount * rowCount;
    }

    public void drawTile(Graphics g, int x, int y, int width, int height, int frameNumber) {
        if (image != null) {
            int tileWidth = image.getWidth() / columnCount;
            int tileHeight = image.getHeight() / rowCount;
            int tileY = frameNumber / columnCount;
            int tileX = frameNumber - (columnCount * tileY);
            int dx1 = x;
            int dy1 = y;
            int dx2 = x + width;
            int dy2 = y + height;

            int sx1 = tileX * tileWidth;
            int sy1 = tileY * tileHeight;
            int sx2 = sx1 + tileWidth;
            int sy2 = sy1 + tileHeight;
            g.drawImage(image, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, this);
        }
    }
}
